package jmine.tec.report.impl.table.csv;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;

import jmine.tec.report.api.table.ReportCell;
import jmine.tec.report.impl.table.RendererParameterInterface;
import jmine.tec.report.impl.table.ReportTableBuilder;
import bancosys.tec.utils.formatter.NumberFormatter;

/**
 * Renderizador de células do tipo numérico.
 * 
 * @author katsuo.ogawa
 */
public class NumberCellCSVRenderer implements ReportCellCSVRenderer {

    /**
     * {@inheritDoc}
     */
    public void render(OutputStream outputStream, ReportCell cell, String charset) throws IOException {
        String numberValue = "";
        if (cell.getValue() != null) {
            numberValue = NumberFormatter.formatDecimalNumber(this.getBigDecimalValue(cell), this.getDecimals(cell));
            numberValue = numberValue.replaceAll("[^0-9]", "");
        }

        outputStream.write(numberValue.toString().getBytes(charset));
    }

    /**
     * Retorna o número de casas decimais que deve ser utilizada na formatação
     * 
     * @param cell cell
     * @return integera
     */
    private int getDecimals(ReportCell cell) {
        RendererParameterInterface rpi = new RendererParameterInterface(cell);
        Integer decimals = rpi.getDecimals();
        return (decimals != null) ? decimals : this.getValueScale(cell);
    }

    /**
     * Tenta obter a quantidade de casas decimais de um BigDecimal
     * 
     * @param cell cell
     * @return BigDecimal
     */
    private int getValueScale(ReportCell cell) {
        if (cell.getValue() == null) {
            return 0;
        } else if (BigDecimal.class.isInstance(cell.getValue())) {
            return BigDecimal.class.cast(cell.getValue()).scale();
        } else if (Number.class.isInstance(cell.getValue())) {
            return new BigDecimal(Number.class.cast(cell.getValue()).doubleValue()).scale();
        } else {
            return new BigDecimal(cell.getValue().toString()).scale();
        }
    }

    /**
     * Tenta obter o valor da célula na forma de um BigDecimal
     * 
     * @param cell cell
     * @return BigDecimal
     */
    private BigDecimal getBigDecimalValue(ReportCell cell) {
        if (cell.getValue() == null) {
            return null;
        } else if (BigDecimal.class.isInstance(cell.getValue())) {
            return BigDecimal.class.cast(cell.getValue());
        } else if (Number.class.isInstance(cell.getValue())) {
            return new BigDecimal(Number.class.cast(cell.getValue()).doubleValue());
        } else {
            return new BigDecimal(cell.getValue().toString());
        }
    }

    /**
     * {@inheritDoc}
     */
    public String getRendererType() {
        return ReportTableBuilder.TYPE_NUMBER;
    }

}
